home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 22
/
Cream of the Crop 22.iso
/
program
/
cgazv4n2.zip
/
SHROUD.C
< prev
next >
Wrap
C/C++ Source or Header
|
1989-10-25
|
11KB
|
314 lines
/******************************** SHROUD.C *********************************
* Program: shroud.c - A code shrouder
* Author: Philip J. Erdelsky
* Compilers: Turbo C 2.0, MSC 5.1
* Memory Models: any
* Compile time switches: NESTCOM - if defined, nested comments are ok
*
* Usage: (1) expects list of keywords that are not to be translated in
* a file named "keywords". This file contains one keyword
* per line. Blank lines and lines beginning with a
* semi-colon are ignored.
* (2) expects a file containing a list of files to be translated
* in a file named "filelist". Each line of "filelist" should
* contain a pair of files names separated by white space:
* infile1.c outfile1.c
* infile2.c outfile2.c
* ...
* (3) the table of symbol translations is written to stdout
*
* Date: Sep. 1989 May be used freely if authorship is acknowledged.
***********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define MAXLAB 31 /* max number of characters that are meaningful
in a symbol's name */
#define MAXFS 64 /* max length of a file specification */
#if 0
#define NESTCOM 0 /* define this to allow nested comments */
#endif
/******** common data items **************/
/* the structure we use to store symbol names */
typedef struct label_table_entry {
struct label_table_entry *next;
int number; /* translate it to Lnumber */
char name[1]; /* name of symbol is here and in following bytes */
} label;
static int current_char; /* current source file character */
static FILE *source_file;
static FILE *destination_file;
static int label_number = 1;
/********************** error handlers ***********************/
void error_exit(s)
char *s;
{
fputs(s, stderr);
exit(1);
}
void cant_open(s)
char *s;
{
fprintf(stderr, "Can't open %s\n", s);
exit(1);
}
void unexpected_EOF()
{
error_exit("Unexpected end of file");
}
/********************** input/output *************************/
int next_char()
{
return (current_char = getc(source_file));
}
int put_current_char_get_next()
{
putc(current_char, destination_file);
return (next_char());
}
/****************** string & comment scanners ****************/
/* scan input until end of string delimited by terminator */
void scan_string(int terminator)
{
put_current_char_get_next();
while(1) {
if (current_char == terminator)
break;
if (current_char == '\\')
put_current_char_get_next();
put_current_char_get_next();
}
put_current_char_get_next();
}
/* scan a comment, discarding its contents */
void scan_comment()
{
next_char();
while (current_char!=EOF) {
#ifdef NESTCOM
if (current_char == '/') {
if (next_char() == '*')
scan_comment();
}
else
#endif
if (current_char == '*') {
if (next_char() == '/') {
next_char();
return;
}
}
else
next_char();
}
unexpected_EOF();
}
/********************** main routine *************************/
void main()
{
label *first_label = NULL; /* list of translated symbols */
label *last_label;
label *first_keyword = NULL; /* list of symbols to leave alone */
label *last_keyword;
label *keyword, *this_label;
int c, i;
FILE *fp;
char name_buf[MAXLAB+1];
/**** read in list of keywords and library function names ****/
fp = fopen ("KEYWORDS", "r");
if (fp == NULL)
error_exit("Can't open KEYWORDS file");
while (( c = getc (fp)) != EOF) {
/* skip blank lines */
if (c == '\n')
continue;
/* skip ;xxx lines */
if (c == ';') {
while (c != '\n' && c != EOF)
c=getc(fp);
continue;
}
/* looks like a symbol */
i = 0;
do {
if (i < MAXLAB)
name_buf[i++] = c;
}
while ((c = getc (fp)) != '\n' && c != EOF);
name_buf[i] = '\0';
if (( keyword=(label *) malloc (sizeof (label) + i) ) == NULL)
error_exit("Insufficient memory");
strcpy (keyword->name, name_buf);
if (first_keyword == NULL)
first_keyword = last_keyword = keyword;
else {
last_keyword->next = keyword;
last_keyword = keyword;
}
keyword->next = NULL;
}
fclose(fp);
/**** open file list file, starting retrieving file names ****/
fp = fopen("FILELIST", "r");
if (fp == NULL) error_exit("Can't open FILELIST file");
puts("/* symbol translations generated by shroud.exe for\n");
while ((c = getc(fp)) != EOF) {
static char first_specs[MAXFS+1];
static char second_specs[MAXFS+1];
i = 0;
while (!isspace(c)) {
if (c == '\n' || c == EOF)
error_exit("Destination file specifications missing");
if (i<MAXFS) first_specs[i++] = c;
else error_exit("Source file specifications too long");
c = getc(fp);
}
first_specs[i] = 0;
while(isspace(c)) /* skip intervening white space */
c = getc(fp);
i = 0;
while (!isspace(c)) {
if (c == EOF)
error_exit("Destination file specifications missing");
if (i < MAXFS) second_specs[i++] = c;
else error_exit("Destination file specifications too long");
c = getc(fp);
}
second_specs[i] = 0;
/* now report the file names and open them */
printf(" %s -> %s\n", first_specs, second_specs);
if ((source_file = fopen (first_specs,"r")) == NULL)
cant_open(first_specs);
if ((destination_file = fopen (second_specs,"w")) == NULL)
cant_open(second_specs);
/* start scanning */
next_char();
while (current_char!=EOF) {
if (current_char == '/') {
if (next_char() == '*') scan_comment();
else putc ('/', destination_file);
}
else if (current_char == '\'' || current_char == '"') {
scan_string(current_char);
}
else if (isdigit(current_char)) {
do put_current_char_get_next();
while (isalnum(current_char) || current_char == '.');
}
else if (isalpha(current_char) || current_char == '_') {
i = 0;
do {
if (i<MAXLAB) name_buf[i++] = current_char;
next_char();
}
while (isalpha(current_char) || current_char == '_');
name_buf[i] = '\0';
/**** first, is this a keyword? ****/
for (keyword = first_keyword; keyword != NULL;
keyword = keyword->next)
if (strcmp(keyword->name, name_buf) == 0) break;
if (keyword != NULL)
fputs(name_buf, destination_file);
/**** not a keyword. translate it ****/
else {
/* Is this label already known? */
label *t;
label *previous = NULL;
for (t = first_label; t != NULL; t = t->next) {
if (strcmp (t->name,name_buf) == 0)
break;
previous = t;
}
if (t == NULL) /* If not, put it into the table */ {
if (( this_label=(label *) malloc (sizeof(label) + i))
== NULL)
error_exit("Insufficient memory");
strcpy (this_label->name, name_buf);
this_label->number = label_number++;
if (first_label == NULL)
first_label = last_label = this_label;
else {
last_label->next = this_label;
last_label = this_label;
}
this_label->next = NULL;
t = this_label;
}
else /* if so, move it to the beginning of the table */ {
if (previous != NULL) {
previous->next = t->next;
t->next = first_label;
first_label = t;
if (last_label == t)
last_label = previous;
}
}
fprintf (destination_file, "L%05d", t->number);
}
}
else if (current_char == '\n') {
put_current_char_get_next();
while (current_char == ' ' || current_char == '\t')
next_char();
}
else if (current_char == '#') {
char cpp_directive[9];
i = 0;
put_current_char_get_next();
while (isalpha(current_char)) {
if ( i < 8)
cpp_directive[i++] = current_char;
put_current_char_get_next();
}
cpp_directive[i] = 0;
/* we handle #include differently - musn't touch! */
if (strcmp (cpp_directive, "include") == 0) {
while (current_char != '\n' && current_char != EOF)
put_current_char_get_next();
}
}
else {
put_current_char_get_next();
}
}
}
/**** now write out translation table ****/
puts(" */");
putchar('\n');
for (keyword = first_label; keyword != NULL; keyword = keyword->next)
printf("#define L%05d %s\n", keyword->number, keyword->name);
}